from typing import Dict, Optional, Any
from datetime import datetime
from dataclasses import dataclass
import logging

logger = logging.getLogger(__name__)

@dataclass
class DownloadProgress:
    task_id: str
    total_size: int
    downloaded_size: int = 0
    speed: float = 0
    status: str = 'pending'
    error: Optional[str] = None
    started_at: datetime = datetime.now()

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'task_id': self.task_id,
            'total_size': self.total_size,
            'downloaded_size': self.downloaded_size,
            'speed': self.speed,
            'status': self.status,
            'error': self.error,
            'started_at': self.started_at.isoformat(),
            'progress': (self.downloaded_size / self.total_size * 100) if self.total_size > 0 else 0
        }

class ProgressManager:
    _instance = None
    _progress: Dict[str, DownloadProgress] = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def create_task(self, task_id: str, total_size: int = 0, platform: str = '', author: str = '', title: str = ''):
        """创建下载任务进度记录"""
        # 生成任务说明
        description = f"下载{platform}内容"
        if author:
            description += f"-作者{author}"
        if title:
            description += f"-{title}"
        
        progress = DownloadProgress(task_id=task_id, total_size=total_size)
        self._progress[task_id] = progress
        logger.info(f"Created task: {task_id} - {description}")
    
    def update_progress(self, task_id: str, downloaded_size: int, status: str):
        """更新下载进度"""
        if task_id in self._progress:
            progress = self._progress[task_id]
            progress.downloaded_size = downloaded_size
            progress.status = status
            
            # 计算下载速度
            elapsed = (datetime.now() - progress.started_at).total_seconds()
            if elapsed > 0:
                progress.speed = downloaded_size / elapsed
            
            logger.debug(f"Updated task {task_id}: {downloaded_size}/{progress.total_size}")
    
    def complete_task(self, task_id: str):
        """标记任务完成"""
        if task_id in self._progress:
            progress = self._progress[task_id]
            progress.status = 'completed'
            progress.downloaded_size = progress.total_size
            logger.info(f"Task completed: {task_id}")
    
    def fail_task(self, task_id: str, error: str):
        """标记任务失败"""
        if task_id in self._progress:
            progress = self._progress[task_id]
            progress.status = 'failed'
            progress.error = error
            logger.error(f"Task failed: {task_id} - {error}")
    
    def get_progress(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取下载进度"""
        progress = self._progress.get(task_id)
        if progress:
            return progress.to_dict()
        return None

    def cleanup_old_tasks(self, max_age_hours: int = 24):
        """清理旧的任务记录"""
        now = datetime.now()
        old_tasks = [
            task_id for task_id, progress in self._progress.items()
            if (now - progress.started_at).total_seconds() > max_age_hours * 3600
        ]
        for task_id in old_tasks:
            del self._progress[task_id]
        if old_tasks:
            logger.info(f"Cleaned up {len(old_tasks)} old tasks")

    def get_all_tasks(self) -> Dict[str, Dict[str, Any]]:
        """获取所有任务的进度"""
        return {
            task_id: progress.to_dict()
            for task_id, progress in self._progress.items()
        }